# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>.
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, version 2 or later, which is
# incorporated herein by reference.

# Further modifications made by Jacqueline McKoy <jaxmckoy@gmail.com>
import shelve

class SlopeOne(object):
    def __init__(self):
        self.diffs = {}
        self.freqs = {}

    def getRecomendations(self, judge, limit):
        preds, freqs = {}, {}
        for item, rating in judge.iteritems():
            for diffitem, diffratings in self.diffs.iteritems():
                try:
                    freq = self.freqs[diffitem][item]
                except KeyError:
                    continue
                preds.setdefault(diffitem, 0.0)
                freqs.setdefault(diffitem, 0)
                preds[diffitem] += freq * (diffratings[item] + rating)
                freqs[diffitem] += freq
		
	predlist =  [(item, value / freqs[item])
                     for item, value in preds.iteritems()
                      if item not in judge and freqs[item] > 0]
	# sort the prediction matrix in desc order of score; I wonder why this was missing
	predlist.sort(lambda x,y: cmp(y[1],x[1]))
	return predlist[:int(limit) -1]

    def update(self, userdata):
        for ratings in userdata.itervalues():
            for item1, rating1 in ratings.iteritems():
                self.freqs.setdefault(item1, {})
                self.diffs.setdefault(item1, {})
                for item2, rating2 in ratings.iteritems():
                    self.freqs[item1].setdefault(item2, 0)
                    self.diffs[item1].setdefault(item2, 0.0)
                    self.freqs[item1][item2] += 1
                    self.diffs[item1][item2] += rating1 - rating2
        for item1, ratings in self.diffs.iteritems():
            for item2 in ratings:
                ratings[item2] /= self.freqs[item1][item2]
